#pragma once
#include "bsp/bsp.h" // IWYU pragma: export
#include "os/types.h"
#define MAX_TASK 32

#define TIMER_INIT(timer, handler) {&timer, &timer, handler}
typedef uint32_t (*TskFunction_t)( void * );

typedef struct os_task {
	u64 time;
	struct os_task *next;
	TskFunction_t handler;
	void *params;
} os_task_t;

typedef struct os_timer {
	struct os_timer *prev;
	struct os_timer *next;
	void (*handler)(struct os_timer *timer);
	u64 time;
} os_timer_t;

static inline bool os_timer_started(os_timer_t *timer)
{
	return timer->next != timer;
}

static inline bool os_timer_stopped(os_timer_t *timer)
{
	return timer->next == timer;
}

static inline void os_timer_init(os_timer_t *timer, void (*handler)(struct os_timer *)) {
	timer->prev = timer->next = timer;
	timer->handler = handler;
}


#ifndef USE_MEX_CMD
static inline uint32_t cpu_enter_critical() {
    uint32_t primask = __get_PRIMASK();
    __disable_irq();
    return primask;
}

static inline void cpu_exit_critical(uint32_t priority_mask) {
    __set_PRIMASK(priority_mask);
}

static inline bool is_in_irq_context (void) {
  return (__get_IPSR() != 0U);
}
#else
static inline bool is_in_irq_context (void) {
	return false;
}
#endif

u32 os_timestemp(void);
u32 os_delta_ms(uint32_t prev_ms);
u64 os_get_mseconds(void);
u32 os_get_seconds(void);
void os_delay_ms(uint32_t ms);
void os_timer_post(os_timer_t *timer, u32 delay);
void os_timer_cancel(os_timer_t *timer);
void os_task_add(os_task_t *task);
void os_task_run(void);
os_task_t *os_task_create(TskFunction_t, void *);

extern void *pvPortMalloc( size_t xWantedSize );
#define os_alloc pvPortMalloc
extern void vPortFree(void *);
#define os_free vPortFree